package au.gov.bom.weather;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.bind.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * An implementation of BOM weather service facade
 *  
 * @author Sergiy Litsenko
 *
 */
public class DefaultBomWeatherService implements BomWeatherService {
	// logger
	protected Log log = LogFactory.getLog (this.getClass());

	/**
	 * Default constructor
	 */
	public DefaultBomWeatherService() {
	}

	/* (non-Javadoc)
	 * @see au.gov.bom.weather.BomWeatherService#getForecast(java.lang.String)
	 */
	@Override
	public ProductType getForecast(String code) throws BomWeatherServiceException {
		try {
			return getForecast(new URL (BOM_SERVICE_URL + code));
		} catch (MalformedURLException e) {
			// log error
			String errMsg = String.format("Unable to get BOM weather service data for %1$s code", code); 
			log.error(errMsg, e);
			// throw
			throw new BomWeatherServiceException (errMsg, e);
		}
	}

	/* (non-Javadoc)
	 * @see au.gov.bom.weather.BomWeatherService#getForecast(java.net.URI)
	 */
	@Override
	public ProductType getForecast(URL codeUri) throws BomWeatherServiceException {
		// is URI null?
		if (codeUri == null) {
			// return
			return null;
		}
		
		ProductType product = null;
		
        try {
			// initialisation of a JAXBContext
			JAXBContext ctx = JAXBContext.newInstance("au.gov.bom.weather"); 
			
			// create unmarshaller 
			Unmarshaller unmarshaller = ctx.createUnmarshaller();
			
			// debug
			if (log.isDebugEnabled()) {
				log.debug(String.format("Loading BOM weather service data from %1$s", codeUri));
			}
			
			// fetch and unmarshall product
			//product = (ProductType)unmarshaller.unmarshal(codeUri);
			JAXBElement<?> o = (JAXBElement<?>)unmarshaller.unmarshal(codeUri);
			product = (ProductType)o.getValue();
			
			// debug
			if (log.isDebugEnabled()) {
				log.debug(String.format("Loaded BOM weather service data from %1$s -> %2$s", codeUri, o));
				log.debug(ToStringBuilder.reflectionToString (product));
			}
			
			// return
			return product;
		} catch (JAXBException e) {
			// log error
			String errMsg = String.format("Unable to get BOM weather service data for %1$s code URI due to unmarshalling error.", codeUri); 
			log.error(errMsg, e);
			// throw
			throw new BomWeatherServiceException (errMsg, e);
		}
	}

	@Override
	public URL getImage(int weatherGraphicCode) {
		String imageUrl = "";
		switch (weatherGraphicCode) {
		case WGC_SUNNY : imageUrl = "sunny.png"; break; 
		case WGC_CLEAR : imageUrl = "clear.png"; break;
		case WGC_PARTLY_CLOUDY : imageUrl = "partly-cloudy.png"; break;
		case WGC_CLOUDI : imageUrl = "cloudy.png"; break;
		case WGC_HAZY  : imageUrl = "haze.png"; break;
		case WGC_LIGHT_RAIN : imageUrl = "light-rain.png"; break;
		case WGC_WINDY  : imageUrl = "wind.png"; break;
		case WGC_FOG : imageUrl = "fog.png"; break;
		case WGC_SHOWER : imageUrl = "showers.png"; break;
		case WGC_RAIN : imageUrl = "rain.png"; break;
		case WGC_DUSTY : imageUrl = "dust.png"; break;
		case WGC_FROST : imageUrl = "frost.png"; break;
		case WGC_SNOW : imageUrl = "snow.png"; break;
		case WGC_STORM : imageUrl = "storm.png"; break;
		case WGC_LIGHT_SHOWER : imageUrl = "light-showers.png"; break;
		// default
		default: break;
		}
		// convert to URL
		try {
			return new URL (BOM_IMAGES_URL + imageUrl);
		} catch (MalformedURLException e) {
			return null;
		}
	}

}
